using System.Threading.Channels;
using Gateway.IApplication.RequestLog;
using Gateway.IApplication.RequestLog.Input;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Gateway.Application.Channels;
/// <summary>
/// 
/// </summary>
public class RequestLogChannel
{
    private Channel<AddRequestLogInput> _channels;
    private readonly ILogger<RequestLogChannel> _logger;
    private readonly IServiceScopeFactory _scopeFactory;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="scopeFactory"></param>
    public RequestLogChannel( ILogger<RequestLogChannel> logger,
        IServiceScopeFactory scopeFactory)
    {
        _logger = logger;
        _scopeFactory = scopeFactory;
    }
    /// <summary>
    /// 
    /// </summary>
    public void Start()
    {
        _channels = Channel.CreateUnbounded<AddRequestLogInput>(new UnboundedChannelOptions()
        {
            AllowSynchronousContinuations = false
        });
        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 5; i++)
        {
            var taskItem = Task.Factory.StartNew(Reader, TaskCreationOptions.LongRunning);
            tasks.Add(taskItem);
        }

        Task.WhenAll(tasks);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    private async Task Reader()
    {
        while (await _channels.Reader.WaitToReadAsync())
        {
            var success = _channels.Reader.TryRead(out var message);
            if (success)
            {
                try
                {
                    _logger.LogInformation("【发送消息】Reader 正在执行发送消息。。。。");
                    using (var scope = _scopeFactory.CreateScope())
                    {
                        var service = scope.ServiceProvider.GetService<IRequestLogApp>();
                        await service.Add(message);
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError("【消费失败】 Reader 当前消息：" + JsonConvert.SerializeObject(message) + ",失败原因：" +
                                     JsonConvert.SerializeObject(e));
                }
            }
        }
    }
    /// <summary>
    /// 写入消息
    /// </summary>
    /// <param name="command"></param>
    public async Task Write(AddRequestLogInput command)
    {
        _logger.LogInformation("【写入消息】WriteOperatorLog 正在执行写入消息。。。。");
        await _channels.Writer.WriteAsync(command);
    }
}